package com.yzl.frelink.service.matlab;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.yzl.frelink.entities.chart.Transition;
import com.yzl.frelink.entities.component.Chart;
import com.yzl.frelink.entities.component.Component;
import com.yzl.frelink.entities.model.Model;

@Service
public class TransitionCompiler {
    @Value("${frelink.transCode}")
    private String transCode;

    public String compileTransitions(Model model) {
        int chartCount = 0;
        List<String> chartTrans = new ArrayList<>();
        for (Chart chart : model.getCharts()) {
            chartCount++;
            StringBuilder sb = new StringBuilder();
            sb.append("sources = [").append(compileSources(chart)).append("];\n");
            sb.append("destinations = [").append(compileDestinations(chart)).append("];\n");
            sb.append("labelStringsForTrans = [").append(compileLabels(chart)).append("];\n");
            sb.append("destinationOClocks = [").append(compileDirections(chart)).append("];\n");
            sb.append("setTrans(charts(").append(chartCount).append("), states").append(chartCount);
            sb.append(", sources, destinations, labelStringsForTrans, destinationOClocks);\n");
            chartTrans.add(sb.toString());
//             chartTrans.add("""
// sources = [%s];
// destinations = [%s];
// labelStringsForTrans = [%s];
// destinationOClocks = [%s];
// setTrans(charts(%d), states%d, sources, destinations, labelStringsForTrans, destinationOClocks);
// """.formatted(compileSources(chart), compileDestinations(chart), compileLabels(chart), compileDirections(chart), chartCount, chartCount));

        }
        return transCode + "\n" + String.join("\n", chartTrans);
//         return """
// %% create transitions
// %% position of the single transition between two states will be not at the middle
// %% if there are two, they will be at the two sides 
// function transition = addTrans(ch, s, source, destination, labelString, destinationOClock)
//   transition = Stateflow.Transition(ch);
//   transition.Destination = s(destination);
//   if source ~= 0
//     transition.Source = s(source);
//     transition.LabelString = labelString;
//     %% transition.SourceOClock = 3;
//     %% transition.DestinationOClock = 9;
//   else
//     transition.DestinationOClock = 9;
//     transition.SourceEndPoint = transition.DestinationEndPoint-[20 0];
//     transition.MidPoint = transition.DestinationEndPoint-[10 0];
//   end
// end

// function setTrans(chart, states, sources, destinations, labelStringsForTrans, destinationOClocks)
//   mn = size(sources);
//   nowSize = mn(2);
//   for i = 1 : nowSize
//     t(i) = addTrans(chart, states, sources(i), destinations(i), labelStringsForTrans(i), destinationOClocks(i));
//   end
// end

// %s
// """.formatted(String.join("\n", chartTrans));
    }

    private String compileSources(Chart chart) {
        List<String> sources = new ArrayList<>();
        for (Transition transition : chart.getTransitions()) {
            if (chart.getStatesCompilingOrder().indexOf(transition.getFrom().getName()) != -1) {
                sources.add(String.valueOf(chart.getStatesCompilingOrder().indexOf(transition.getFrom().getName()) + 1));
            } else {
                sources.add("0");
            }
        }
        return String.join(", ", sources);
    }

    private String compileDestinations(Chart chart) {
        List<String> destinations = new ArrayList<>();
        for (Transition transition : chart.getTransitions()) {
            destinations.add(String.valueOf(chart.getStatesCompilingOrder().indexOf(transition.getTo().getName()) + 1));
        }
        return String.join(", ", destinations);
    }

    private String compileLabels(Chart chart) {
        List<String> labels = new ArrayList<>();
        for (Transition transition : chart.getTransitions()) {
            labels.add(transition.getMatlabLabel());
        }
        return String.join(", ", labels);
    }

    private String compileDirections(Chart chart) {
        List<String> directions = new ArrayList<>();
        for (Transition transition : chart.getTransitions()) {
            directions.add("0");
        }
        return String.join(", ", directions);
    }
}
